from functools import reduce
from typing import List

# CLASS 
class PipeArgs:
    def __init__(self):
        self.filters = []

    def add_filter(self, filter):
        self.filters.append(filter)

    def process_with_args(self, data, args):
        return reduce(lambda result, filter: filter.apply_with_args(result, args[self.filters.index(filter)]), self.filters, data)


class FilterArgs:
    def __init__(self, transform):
        self.transform = transform

    def apply_with_args(self, data, *args):
        return self.transform(data, *args)





# IMPLEMENTATION 
def print_return(aditional_text,data):
    print(f"{aditional_text} {data}")
    return data


def is_prime(n):
    if (n < 2) or (n % 2 == 0 and n != 2) or (n % 3 == 0 and n != 3):
        return False
    for i in range(5, int(n ** 0.5) + 1, 6):
        if (n % i == 0) or (n % (i + 2) == 0):
            return False
    return True


def to_int(n):
    try:
        return int(n)
    except:
        return -1

def get_int_input():
    return to_int(input("Enter nuber f as folows = x %\ f  != 0"))

def example_hello_world_args():
    myPipe = PipeArgs()

    prefixFilter = FilterArgs(lambda data, prefix: prefix + data)
    capitalizeFilter = FilterArgs(lambda data, _: data.upper())
    appendFilter = FilterArgs(lambda data, suffix: data + suffix)

    myPipe.add_filter(prefixFilter)
    myPipe.add_filter(capitalizeFilter)
    myPipe.add_filter(appendFilter)

    filtersArgs = ["Hello, ", None ,"!"]
    result = myPipe.process_with_args("world", filtersArgs)
    print(result)


def example_complex_with_args():
    pipe1 = PipeArgs()

    filter_split = FilterArgs(lambda data, _: data.split(" "))
    filter_number = FilterArgs(lambda data, _: [to_int(d)  for d in data] )
    filter_just_number_higher_than_zero = FilterArgs(lambda data, _:  [d for d in data if d > 0])
    filter_printer  = FilterArgs(lambda data, aditional_info: print_return(aditional_info, data))


    pipe1.add_filter(filter_split)
    pipe1.add_filter(filter_number)
    pipe1.add_filter(filter_just_number_higher_than_zero)
    pipe1.add_filter(filter_printer)
    
    
    pipe2 = PipeArgs()

    pipe2.add_filter(FilterArgs(lambda data, factor: [d for d in data if (d % factor != 0) ]))
    pipe2.add_filter(filter_printer)
    
    pipe3 = PipeArgs()
    pipe3.add_filter(FilterArgs(lambda data, _: [d for d in data if is_prime(d) ]))
    pipe3.add_filter(filter_printer)


    data = input("Enter list of numbers, use space as divider: ")
    result = pipe1.process_with_args(data, [None,None,None,"result of first pipeline = "])
    result2 = pipe2.process_with_args(result, [to_int(input("Enter nuber f as folows = x % f != 0 : ")),"result of second pipeline = "])
    result3 = pipe3.process_with_args(result, [None,"result of third pipeline = "])



if __name__ == '__main__':
    while True:
        
        if int(input("select example: 1-hello world | 2-complex :  ")) == 1:
            example_hello_world_args()
        else:
            example_complex_with_args()
